package com.google.code.securityflow.cfg

import com.google.code.securityflow.graphviz.{GraphvizMultiNode, GraphvizCluster}
import util.Random

class Function(val id: Int, val entry: EntryBlock, val exit: ExitBlock) {

  def basicBlocks = {
    def visit(block: BasicBlock, visited: Set[BasicBlock]): Set[BasicBlock] = {
      var seen = visited + block;
      for (successor <- block.successors) {
        if (!seen.contains(successor)) {
          seen = seen ++ visit(successor, seen);
        }
      }
      seen;
    }
    visit(entry, Set.empty);
  }

  def toGraphviz: GraphvizCluster = {
    var block2multiNode: Map[BasicBlock, GraphvizMultiNode] = Map.empty;
    for (basicBlock <- basicBlocks) {
      val multiNode = basicBlock.toGraphviz;
      block2multiNode = block2multiNode + (basicBlock -> multiNode);
    }
    for (basicBlock <- basicBlocks) {
      val multiNode = block2multiNode(basicBlock);
      basicBlock.successors.foreach(b => multiNode.addSuccessor(block2multiNode(b)));
    }
    GraphvizCluster(Random.nextInt(Int.MaxValue), "Function[" + id + "]", block2multiNode.values.toSet);
  }

  override def toString = "Function[" + id + "]";

  def toPrettyString: String = "Function[" + id + "]";

}

